﻿using System;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

namespace SimpComm
{
    public class XMLHelper
    {
        #region String

        public static string Serialize<T>(T Info)
        {
            var Stream = new MemoryStream();
            var xml = new XmlSerializer(typeof (T));
            try
            {
                //序列化对象 
                xml.Serialize(Stream, Info);
            }
            catch (InvalidOperationException)
            {
                return null;
            }
            Stream.Position = 0;
            var sr = new StreamReader(Stream);
            return sr.ReadToEnd();
        }

        public static T Deserialize<T>(string Data)
        {
            var deserializer = new XmlSerializer(typeof (T));
            var queryinfo = default(T);
            try
            {
                using (var reader = new StringReader(Data))
                {
                    queryinfo = (T) deserializer.Deserialize(reader);
                }
                return queryinfo;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        #endregion

        #region StreamReader
        
        public static T Deserialize<T>(StreamReader Data)
        {
            var deserializer = new XmlSerializer(typeof(T));
            var queryinfo = default(T);
            try
            {
                using (var reader = Data)
                {
                    queryinfo = (T)deserializer.Deserialize(reader);
                }
                return queryinfo;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        #endregion

        #region Nested type: CData

        public class CData : IXmlSerializable
        {
            private string m_Value;

            public CData()
            {
            }

            public CData(string p_Value)
            {
                m_Value = p_Value;
            }

            public string Value
            {
                get { return m_Value; }
            }

            #region IXmlSerializable Members

            public void ReadXml(XmlReader reader)
            {
                m_Value = reader.ReadElementContentAsString();
            }

            public void WriteXml(XmlWriter writer)
            {
                writer.WriteCData(m_Value);
            }

            public XmlSchema GetSchema()
            {
                return (null);
            }

            #endregion

            public override string ToString()
            {
                return m_Value;
            }

            public static implicit operator string(CData element)
            {
                return (element == null) ? null : element.m_Value;
            }

            public static implicit operator CData(string text)
            {
                return new CData(text);
            }
        }

        #endregion

        #region 示例

        [Serializable]
        public class XmlQueryInfo
        {
            private CData queryContentSource;

            [XmlElement]
            public string QueryName { get; set; }

            [XmlElement("QueryContentSource", typeof (CData))]
            public CData QueryContentSource
            {
                get { return queryContentSource; }
                set { queryContentSource = value; }
            }
        }

        #endregion

        public static string Serialize1<T>(T value)
        {

            if (value == null)
            {
                return null;
            }

            XmlSerializer serializer = new XmlSerializer(typeof(T));

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Encoding = new UnicodeEncoding(false, false); // no BOM in a .NET string
            settings.Indent = false;
            settings.OmitXmlDeclaration = false;

            using (StringWriter textWriter = new StringWriter())
            {
                using (XmlWriter xmlWriter = XmlWriter.Create(textWriter, settings))
                {
                    serializer.Serialize(xmlWriter, value);
                }
                return textWriter.ToString();
            }
        }

        public static T Deserialize1<T>(string xml)
        {

            if (string.IsNullOrEmpty(xml))
            {
                return default(T);
            }

            XmlSerializer serializer = new XmlSerializer(typeof(T));

            XmlReaderSettings settings = new XmlReaderSettings();
            // No settings need modifying here

            using (StringReader textReader = new StringReader(xml))
            {
                using (XmlReader xmlReader = XmlReader.Create(textReader, settings))
                {
                    return (T)serializer.Deserialize(xmlReader);
                }
            }
        }
    }
}